import logging
import json
import time
from threading import Thread, Event
import time
from typing import List
from sqlalchemy import or_
from common import Result, TaskStatus
from ExtendRegister.model_register import Paragraph, Thesis
from ExtendRegister.db_register import db
from api.talkgpt.service import Service
from api.thesis.service import ThesisServie
from api.user.service import UserService
from api.talkgpt.dantic import ParamThesisId, ParamGenerateSingleParagraph
from api.talkgpt.utils import travelOutlineDict

LOGGING = logging.getLogger(__name__)


def FuncGenerateThesis(flaskApp, thesisId: int, stopEvent: Event):
    task = TaskGenerateThesis(flaskApp, thesisId, stopEvent)
    task.run()


class TaskGenerateThesis:
    def __init__(self, flaskApp, thesisId: int, stopEvent: Event) -> None:
        self.flaskApp = flaskApp
        self.thesisId = thesisId
        self.userInfo = None
        self.thesis = None
        self.stopEvent: Event = stopEvent

    def run(self):
        LOGGING.info(f"TaskGenerateThesis 开始运行 {self.thesisId}")
        with self.flaskApp.app_context():
            try:
                self.getThesis()

                self._updateStatus(TaskStatus.RUNING)
                self.getUser()
                self.genDigest()
                self.genOutline()
                self._updateStatus(TaskStatus.SUCCESS)
            except Exception as e:
                LOGGING.exception(e)
                self._updateStatus(TaskStatus.ERROR)

    def getUser(self):
        ## 用户信息
        userId = self.thesis["uid"]
        res: Result = UserService().get_user_info(userId)
        if not res.isSucc():
            self._updateStatus(TaskStatus.ERROR)
            raise Exception("UID 不能找到用户")

        self.userInfo = res.data
        LOGGING.info(f"userInfo {self.userInfo}")

    def getThesis(self):

        ## 论文信息
        thesis: Thesis = Thesis.query.filter(Thesis.id == self.thesisId).first()
        if thesis is None:
            self._updateStatus(TaskStatus.ERROR)
            raise Exception("thesisId 不能找到")
        self.thesis = thesis

    def genDigest(self):
        body: ParamThesisId = ParamThesisId(
            thesisId=self.thesisId,
            userId=self.userInfo["id"],
            isVipUser=self.userInfo["isVip"],
        )
        res: Result = Service().generateDigest(body)
        if res.is_success():
            LOGGING.info(f"中文摘要  生成成功 thesisiId: {self.thesisId}")
        else:
            LOGGING.error(f"中文摘要 生成失败 thesisiId: {self.thesisId}")

        res: Result = Service().generateDigestEnglish(body)
        if res.is_success():
            LOGGING.info(f"英文摘要 生成成功 thesisiId: {self.thesisId}")
        else:
            LOGGING.error(f"英文摘要 生成失败 thesisiId: {self.thesisId}")

    def genOutline(self):
        ## 从outline中收集段落
        # 摘要

        paraList: List[Paragraph] = (
            Paragraph.query.filter(Paragraph.thesisId == self.thesisId)
            .filter(
                or_(
                    Paragraph.status == TaskStatus.RUNING,
                    Paragraph.status == TaskStatus.INIT,
                )
            )
            .all()
        )
        for p in paraList:
            LOGGING.info(f"开始生成段落{p.title} {p.id}")

            if self.stopEvent.is_set():
                LOGGING.error("收到了 shutdonw 消息，终止任务，退出线程")
                return

            self._updateParagraphStatue(p.id, TaskStatus.RUNING)

            res: Result = Service().generateSingleParagraph(
                ParamGenerateSingleParagraph(
                    id=p.id,
                    thesisId=self.thesisId,
                    paragraphId=p.paraId,
                    title=p.title,
                    userId=self.userInfo["id"],
                    isVipUser=self.userInfo["isVip"],
                )
            )

            if res.is_success():
                self._updateParagraphStatue(p.id, TaskStatus.SUCCESS)
            else:
                self._updateParagraphStatue(p.id, TaskStatus.ERROR)

    def _updateParagraphStatue(self, id, s):
        try:
            p: Paragraph = Paragraph.query.filter(Paragraph.id == id).first()
            p.status = s
            p.save()
            LOGGING.info(f"更新段落 {id} 状态为 {s}")
        except Exception as e:
            LOGGING.exception(str(e))

    def _updateStatus(self, s):
        try:
            t: Thesis = Thesis().query.get(self.thesisId)
            if t is not None:
                t.status = s
                t.save()
        except Exception as e:
            LOGGING.exception(e)


class ParasList:
    def __init__(self) -> None:
        self.paras = []

    def getList(self):
        return self.paras

    def add(self, id, title):
        self.paras.append(
            {
                "title": title,
                "paraId": id,
                "state": "w",
            }
        )

    def getJson(self):
        return json.dumps(self.paras, ensure_ascii=False)

    def setStateRuning(self, id):
        for p in self.paras:
            if p["paraId"] == id:
                p["state"] = "r"
                LOGGING.info(f"更新 {id} 为 生成中")

    def setStateSuccess(self, id):
        for p in self.paras:
            if p["paraId"] == id:
                p["state"] = "s"
                LOGGING.info(f"更新 {id} 为 已完成")

        print(self.paras)

    def setStateError(self, id):
        for p in self.paras:
            if p["paraId"] == id:
                p["state"] = "e"
                LOGGING.info(f"更新 {id} 为 生成错误")
